/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.letmeshare.stockkeeper.stock.module;

import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.Query;
import org.letmeshare.stockkeeper.stock.entities.Item;
import org.letmeshare.stockkeeper.stock.entities.Stock;

/**
 *
 * @author ibisuser1
 */
public class StockModule {
    
    private EntityManager em;
    
    public static StockModule getInstance(EntityManager em) {
        if (em == null) {
            return null;
        }
        return new StockModule(em);
    }
    
    private StockModule(EntityManager em) {
        this.em = em;
    }
    
    public void createStock (Item item) {
        if (item == null) {
            throw new IllegalArgumentException("Item required");
        }
        Stock stock = new Stock();
        stock.setItem(item);
        em.persist(stock);
    }
    
    public Stock getStock (String id) {
        if (id == null) {
            throw new IllegalArgumentException("Id required");
        }
        return em.find(Stock.class, id);
    }
    
    public Stock getStockByItem (Item item) {
        if (item == null) {
            throw new IllegalArgumentException("Item required");
        }
        Query query = em.createQuery("SELECT stock FROM Stock stock WHERE stock.item = :item AND stock.item.obsolete=false");
        query.setParameter("item", item);
        List<Stock> stocks = query.getResultList();
        return stocks.isEmpty() ? null : (Stock)stocks.get(0);
    }
    
    public Stock getStockByItemCode (String code) {
        if (code == null) {
            throw new IllegalArgumentException("Code required");
        }
        Query query = em.createQuery("SELECT stock FROM Stock stock WHERE stock.item.code = :code AND stock.item.obsolete=false");
        query.setParameter("code", code);
        List<Stock> stocks = query.getResultList();
        return stocks.isEmpty() ? null : (Stock)stocks.get(0);
    }
    
    public List<Stock> getStocksByItemName (String name) {
        Query query = em.createQuery("SELECT stock FROM Stock stock WHERE stock.item.name = :name AND stock.item.obsolete=false");
        query.setParameter("name", name);
        return query.getResultList();
    }
    
    public List<Stock> getStocksByCategory (String catCode) {
        Query query = em.createQuery("SELECT stock FROM Stock stock WHERE stock.item.category.code = :catCode AND stock.item.obsolete=false");
        query.setParameter("catCode", catCode);
        return query.getResultList();
    }
    
    public List<Stock> lookUpStocksByItemFeatures (String searchQuery) {
        Query query = em.createQuery("SELECT stock FROM Stock stock LEFT JOIN stock.item.category cat "
                + "WHERE stock.item.code LIKE :searchQuery OR stock.item.name LIKE :searchQuery "
                + "OR (cat.id IS NOT NULL AND cat.code LIKE :searchQuery) "
                + "AND stock.item.obsolete=false");
        query.setParameter("searchQuery", "%" + searchQuery + "%");
        return query.getResultList();
    }
    
    public List<Stock> getAllStocks() {
        Query query = em.createQuery("SELECT stock FROM Stock stock WHERE stock.item.obsolete=false");
        return query.getResultList();
    }
    
    public void addStock (Item item, double qty) {
        if (item == null) {
            throw new IllegalArgumentException("Item required");
        }
        if (qty < 0) {
            throw new IllegalArgumentException("Invalid quantity");
        }
        Stock stock = getStockByItem(item);
        if (stock == null) {
            throw new IllegalArgumentException("Stock not found for item");//TODO throw app exception
        }
        stock.addStock(qty);
        em.merge(stock);
    }
    
    public void addStock (Stock stock, double qty) {
        if (qty < 0) {
            throw new IllegalArgumentException("Invalid quantity");
        }
        if (stock == null) {
            throw new IllegalArgumentException("Stock required");
        }
        stock.addStock(qty);
        em.merge(stock);
    }
    
    public void consume (Item item, double qty) {
        if (item == null) {
            throw new IllegalArgumentException("Item required");
        }
        if (qty < 0) {
            throw new IllegalArgumentException("Invalid quantity");
        }
        Stock stock = getStockByItem(item);
        if (stock == null) {
            throw new IllegalArgumentException("Stock not found for item");//TODO throw app exception
        }
        stock.consumeStock(qty);
        em.merge(stock);
    }
    
    public void consume (Stock stock, double qty) {
        if (qty < 0) {
            throw new IllegalArgumentException("Invalid quantity");
        }
        if (stock == null) {
            throw new IllegalArgumentException("Stock required");
        }
        stock.consumeStock(qty);
        em.merge(stock);
    }
    
}
